﻿using System;
using Xant.Querier.Core;

namespace Xant.Querier.Compilers
{

    /// <summary>
    /// Represents the base class for query specification compilers.
    /// </summary>
    /// <typeparam name="T">The type of the compiled representation of the query specification.</typeparam>
    public abstract class QueryCompiler<T>
    {
        /// <summary>
        /// 欲编译的<see cref="Query"/>对象
        /// </summary>
        public Query Query { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        /// <remarks>之前设计为在调用编译方法时才传入Query对象，但是编译SQL WHERE从句时有诸多不便，改为构造时传入</remarks>
        /// <param name="query">欲编译的<see cref="Query"/>对象</param>
        protected QueryCompiler(Query query)
        {
            this.Query = query;
        }

        /// <summary>
        /// Compiles the specified query specification.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">Can't compile the given query specificaiton as the validation was failed. See InnerException for details.</exception>
        public T Compile()
        {
            try
            {
                //QueryValidator.Validate(Query, true);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(
                    "Can't compile the given query specificaiton as the validation was failed. See InnerException for details.",
                    ex);
            }

            return this.PerformCompile();
        }

        /// <summary>
        /// Compiles the specified query specification into another representation.
        /// </summary>
        /// <returns>Another representation of the query specification.</returns>
        protected abstract T PerformCompile();

    }
}
